package model;
import java.awt.*;
import java.io.Serializable;
import java.util.*;
import javax.swing.ImageIcon;

/**
 * Object for creating a new Player
 * with name, budget, image and all necessary attributes
 * 
 * @author Thomas
 *
 */
public class Player implements Serializable
{
	private static final long serialVersionUID = 1L;
	private String name;
	private ImageIcon playerImage;
	private int x;
	private int y;
	private int budget;
	private int currentField;
	private boolean isAlive;
	private int inJail;
	private ArrayList<Integer> mortgage; //Stores the indices of the streets which have a mortgage on it.
	private boolean isHuman;
	private int jailFreeCard;
	private boolean hasRolled = false;
		
	/**
	 * 
	 * Constructor for the Player object
	 * Instantiates a Player Object with 
	 * relevant attributes and the 
	 * corresponding Image File
	 * 
	 * TODO
	 * The loading of the Image needs to be
	 * dynamic - i.e. use Constructor to determine 
	 * what figure to use as the Image
	 * 
	 * @param name - Name of the Player
	 * @param startField - The Field on which the Player starts
	 * @param startMoney - The starting Funds of the Player
	 */

	public Player(String name, int startField, int startMoney, boolean human, ImageIcon image, int x, int y)
	{
		this.name = name;
		this.currentField = startField;
		this.x = x;
		this.y = y;
		this.budget = startMoney;
		this.isAlive = true;
		this.inJail = 0;
		this.mortgage = new ArrayList<Integer>();
		this.isHuman = human;
		this.playerImage = image;
	}
	
	/**
	 * Method for returning the Player Name
	 * returns the name of the Player as a String
	 * @return returns a String that contains the name of the player.
	 */	
	public String getName()
	{
		return this.name;
	}
	
	/**
	 * Move the Player to the specifier destination
	 * by updating the current Field to the destination field 
	 * as well as changing the X-Y-Coordinates
	 * @param destination - the new Field the Player has to move to
	 */
	public void move(int destination)
	{
		this.currentField = destination;
		//vom urspr�nglichen ersten test evtl nochmal diskutieren wie wirs besser machen
		//this.x = currentField.getX(); 
		//this.y = currentField.getY();
	}
	
	/**
	 * getX()
	 * returns the current X-Coordinate of the Player
	 * @return the X-Coordinate of the player
	 */
	public int getX()
	{
		return x;
	}
	
	
	/**
	 * getY()
	 * returns the current Y-Coordinate of the Player
	 * @return the Y-Coordinate of the player
	 */
	public int getY()
	{
		return this.y;
	}
	
	/**
	 * getField()
	 * returns the current Field of the Player
	 * @return the current Field of the Player
	 */
	public int getCurrentField()
	{
		return this.currentField;
	}
	
	/**
	 * getImage()
	 * returns the Image of the Player
	 * @return the Image loaded by the Player-Object
	 */
	public ImageIcon getImage()
	{
		return this.playerImage;
	}	
	
	/**
	 * getMoney() 
	 * returns the current Funds of the Player
	 * @return the current Funds of the Player
	 */
	public int getMoney()
	{
		return this.budget;
	}
	
	/**
	 * Returns the mortgage ArrayList.
	 * @return Mortgage ArrayList.
	 */
	public ArrayList<Integer> getMortgageList()
	{
		return mortgage;
	}
	
	/**
	 * isAlive()
	 * returns true if the Player is still in the Game
	 * returns false is the Player has stopped playing
	 * (i.e. lost all his/her money)
	 * 
	 * @return the status of the Player
	 */
	public boolean isAlive()
	{
		return this.isAlive;
	}
	
	/**
	 * setAlive()
	 * method for making the player active/inactive
	 * 
	 * @param isAlive
	 * if true  - Player is actively Playing
	 * if false - Marks the Player as "dead"
	 */
	
	public void setAlive(boolean isAlive)
	{
		this.isAlive = isAlive;
	}
	
	/**
	 * Returns the Jail Status of this Player Object
	 * @return The Jail Status
	 */
	
	public int getJailStatus()
	{
		return inJail;
	}
	
	/**
	 * Sets the jail status of the player
	 * 
	 * @param JailStatus an integer representing the jail status (0 = not in jail, 1 = in jail, 2 = 2 tries on rolling etc)
	 */
	public void setJailStatus(int JailStatus)
	{
		this.inJail = JailStatus;
	}
	
	/**
	 * Adds a mortgage to the player
	 * @param street the street on which the player has put a mortgage
	 */
	public void addMortgage(int street)
	{
		mortgage.add(street);
	}
	/**
	 * Removes a mortgage
	 * 
	 * @param street the street
	 */
	public void removeMortgage(int street)
	{
		for(int i = 0; i < mortgage.size(); i++)
		{
			if(street == mortgage.get(i))
			{
				mortgage.remove(i);
			}
		}
	}
	
	/**
	 * removes all mortgages from the player
	 */
	public void removeAllMortgages()
	{
		mortgage.clear();
	}
	
	/**
	 * add money to the player
	 * @param money amount of money to be added
	 */
	public void addMoney(int money)
	{
		this.budget += money;
	}
	
	/**
	 * subtract money from the player
	 * @param money amount to be subtracted
	 */
	public void subtractMoney(int money)
	{
		this.budget -= money;
	}
	
	/**
	 * Get the type of player
	 * @return true if its a human player, false otherwise
	 */
	public boolean isHuman()
	{
		return this.isHuman;
	}
	
	/**
	 * set the type of player
	 * @param human true for human player
	 */
	public void setHuman(boolean human)
	{
		this.isHuman = human;
	}
	
	/**
	 * get the amount of jail free cards
	 * @return amount of jail free cards
	 */
	public int getJailFreeCard()
	{
		return this.jailFreeCard;		
	}
	
	/**
	 * add a jailfreecard
	 */
	public void addJailFreeCard()
	{
		this.jailFreeCard++;
	}
	
	/**
	 * remove a jailfreecard
	 */
	public void removeJailFreeCard()
	{
		this.jailFreeCard--;
	}
	
	/**
	 * set the x-coordinate of the player
	 * @param x the new x coordinate
	 */
	public void setX(int x)
	{
		this.x = x;
	}
	/**
	 * set the y-coordinate of the player
	 * @param y the new y - coordinate
	 */
	public void setY(int y)
	{
		this.y = y;
	}
	
	/**
	 * checks if the player has rolled
	 * @return true if the player has already rolled
	 */
	public boolean hasRolled()
	{
		return this.hasRolled;
	}
	
	/**
	 * set the rolled status
	 * @param status the status
	 */
	public void setRolled(boolean status)
	{
		this.hasRolled = status;
	}
	
	
	/**
	 * destroy the current player object
	 */
	public void destroy()
	{
		try {
			this.finalize();
		} catch (Throwable e) {
			System.err.println("Could not destroy Player");
			e.printStackTrace();
		}
	}
	
}
